#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;

#define MAXN 2000+5

struct edge {
	int u, v, c;
	edge(): u(-1), v(-1), c(0) { }
	edge(int u, int v, int c): u(u), v(v), c(c) { }
};

struct edge_greater {
	bool operator() (edge &lhs, edge &rhs) {
		return (lhs.c > rhs.c);
	}
};

int N;
char buf[MAXN][8];
int FL[MAXN];

int get_dis(char *a, char *b) {
	int cnt = 0;
	for (int i=0; i<7; i++) {
		if (a[i] != b[i]) cnt++;
	}
	return cnt;
}

int main() {
	while (true) {
		scanf("%d", &N);
		if (N==0) break;
		//Input
		for (int i=1; i<=N; i++) {
			scanf("%s", buf[i]);
		}
		priority_queue<edge, vector<edge>, edge_greater> q;
		for (int i=1; i<=N; i++) {
			for (int j=i+1; j<=N; j++) {
				int dis = get_dis(buf[i], buf[j]);
				q.push(edge(i, j, dis));
				q.push(edge(j, i, dis));
			}
		}
		//Kruskal
		for (int i=1; i<=N; i++) {
			FL[i] = i;
		}
		int cnt = 0;
		int sum = 0;
		while (!q.empty()) {
			edge e = q.top(); q.pop();
			if (cnt >= N-1) break;
			if (FL[e.u] == FL[e.v]) continue;
			cnt++;
			sum += e.c;
			int FLeu = FL[e.u];
			int FLev = FL[e.v];
			for (int i=1; i<=N; i++) {
				if (FL[i] == FLev) {
					FL[i] = FLeu;
				}
			}
		}
		//Output
		printf("The highest possible quality is 1/%d.\n", sum);
	}
	return 0;
}
